package com.starrin.tennisfinder.scheduler;

import com.gargoylesoftware.htmlunit.HttpMethod;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.util.NameValuePair;
import com.starrin.tennisfinder.extractors.AvailabilityExtractorMyCourt;
import com.starrin.tennisfinder.model.VenueAvailabilityDataHolder;
import com.starrin.tennisfinder.system.Cache;
import com.starrin.tennisfinder.util.DateUtil;
import com.starrin.tennisfinder.util.WebUtil;
import org.apache.log4j.Logger;

import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by larsstarrin on 06/02/14.
 */
public class RefreshTaskMyCourt implements Runnable {

    private Map<String, VenueAvailabilityDataHolder> newData = new HashMap<>();
    private Cache cache = Cache.getInstance();
    private static final Logger logger = Logger.getLogger(RefreshTaskMyCourt.class);
    private static final int FORESIGHT_DAYS = 15;
    private String venueKey;
    private String clubId;
    private String indoorItems;
    private String outdoorItems;

    public RefreshTaskMyCourt(String venueKey, String clubId, String indoorItems, String outdoorItems) {
        this.venueKey = venueKey;
        this.clubId = clubId;
        this.indoorItems = indoorItems;
        this.outdoorItems = outdoorItems;
    }

    public void run() {
        logger.info("Start refreshing availability data for " + venueKey);
        long start = System.currentTimeMillis();
        try {
            refresh();
            //Put temp data into cache
            for (Map.Entry<String, VenueAvailabilityDataHolder> entry : newData.entrySet()) {
                cache.putEntry(entry.getKey(), venueKey, entry.getValue());
            }
            logger.info("Finished refreshing availability data for " + venueKey + " in " +  (System.currentTimeMillis() - start) / 1000 + " seconds");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void refresh() {
        try {

            WebClient webClient = new WebClient();
            webClient.getOptions().setThrowExceptionOnScriptError(false);
            webClient.getOptions().setJavaScriptEnabled(false);
            HtmlPage page = webClient.getPage("http://www.mycourt.se");

            HtmlForm loginForm = page.getFormByName("login_form");
            HtmlInput loginName = loginForm.getInputByName("log_email");
            HtmlInput loginPassword = loginForm.getInputByName("log_password");
            HtmlSubmitInput submitButton = loginForm.getInputByValue("Logga in");
            loginName.setValueAttribute("lstarrin@hotmail.com");
            loginPassword.setValueAttribute("lap1nkulta");
            submitButton.click();

            webClient.getPage("http://www.mycourt.se/your_clubs.php");
            webClient.getPage("http://www.mycourt.se/table_cust.php?snewrest=" + clubId);

            for (int i = 0; i < FORESIGHT_DAYS; i++) {
                Calendar cal = new GregorianCalendar();
                cal.add(Calendar.DAY_OF_MONTH, i);
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
                String dateString = df.format(cal.getTime());
                String todayInMillis = new DateUtil().getAsMillisString(cal);

                //Select date
                WebRequest selectDateRequest = new WebRequest(new URL("http://www.mycourt.se/table_cust.php"), HttpMethod.POST);
                List<NameValuePair> params = new ArrayList<>();
                params.add(new NameValuePair("today_cal", todayInMillis));
                selectDateRequest.setRequestParameters(params);
                HtmlPage pageDateSelected = webClient.getPage(selectDateRequest);
                String response = pageDateSelected.getWebResponse().getContentAsString();

                //Extract data
                response = WebUtil.getReducedResponse(response, "veckoöversikt");
                if(response != null) {
                    VenueAvailabilityDataHolder dataHolder = new AvailabilityExtractorMyCourt().extractVenueAvailability(response, "http://www.mycourt.se", indoorItems, outdoorItems);
                    newData.put(dateString, dataHolder);
                }
            }

        } catch(Exception e) {
            logger.error("Error refreshing data", e);
        }
    }

}
